package org.ee.system.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.ee.core.constant.ResultCode;
import org.ee.core.util.GuavaUtil;
import org.ee.core.util.serialize.JsonUtil;
import org.ee.system.service.JwtProvider;
import org.ee.system.service.bo.UserDetailBo;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.io.IOException;
import java.util.Map;

/**
 * 认证过滤器
 *
 * @Author jokr
 * @Date 2025/8/20 下午2:40
 */
@WebFilter("/*")
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    private final JwtProvider jwtProvider;

    public JwtAuthenticationFilter(JwtProvider jwtProvider) {
        this.jwtProvider = jwtProvider;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse rep = (HttpServletResponse) response;
        String token = req.getHeader("Authorization");

        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            if (!jwtProvider.validToken(token)) {
                rep.setStatus(ResultCode.UNAUTHORIZED.getCode());
                rep.setContentType("application/json;charset=UTF-8");
                Map<String, Object> map = GuavaUtil.newHashMap(
                        "code", ResultCode.UNAUTHORIZED.getCode(),
                        "msg", "token已过期",
                        "data", "");
                ObjectMapper objectMapper = JsonUtil.getJsonMapper();
                rep.getWriter().write(objectMapper.writeValueAsString(map));
                return;
            }
            long userId = Long.parseLong(jwtProvider.getUsername(token));
            String username=jwtProvider.getClaim(token,"username",String.class);
            UserDetailBo userDetailBo=new UserDetailBo(userId,username,null);
            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(userDetailBo, null, null);
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }
        chain.doFilter(request, response);
    }
}
